import * as path from 'path'
// @ts-ignore
import camelCase from 'camelcase';
// @ts-ignore
import _fs = require('fs')

const ipcMain = require('electron').ipcMain;

const fs = _fs.promises

export function camelcase(s: string): string {
    return camelCase(s)
}

export function capital(s: string): string {
    return s.charAt(0).toUpperCase() + s.slice(1);
}

export function toPropertyName(s: string) {
    return camelcase(s)
}

export function toClassName(s: string) {
    return capital(camelcase(s))
}

export function toPackageName(s: string) {
    return camelcase(s).toLowerCase()
}

/**
 * @param root 根目录
 * @param recur 是否递归子目录
 * @param type 全部0 仅文件1 仅文件夹2
 */
export async function listFiles(root: string, recur = false, type = 0) {
    root = absPath(root)
    const dd = await fs.readdir(root)
    const ret: string[] = [];
    for (const d of dd) {
        const abs = path.join(root, d)
        const stat = await fs.stat(abs)
        const b: boolean = (type === 0) || (type === 1 && stat.isFile()) || (type === 2 && stat.isDirectory())
        if (b) {
            ret.push(abs)
        }
        if (recur && stat.isDirectory()) {
            const chi = await listFiles(abs, recur, type)
            ret.push(...chi)
        }
    }
    return ret;
}

export async function dirs(root: string, recur = false) {
    return await listFiles(root, recur, 2);
}

export async function files(root: string, recur = false) {
    return await listFiles(root, recur, 1)
}

export async function readFile(file: string) {
    file = absPath(file)
    return await fs.readFile(file, {encoding: 'utf-8'})
}

export async function writeFile(file: string, content: string) {
    file = absPath(file)
    const pathInfo = path.parse(file)
    if (!await exists(pathInfo.dir)) {
        await fs.mkdir(pathInfo.dir, {recursive: true})
    }
    await fs.writeFile(file, content, {encoding: 'utf-8'})
}

export async function exists(file: string) {
    file = absPath(file)
    try {
        await fs.stat(file)
        return true
    } catch (ignore) {
    }
    return false
}

export function absPath(p: string) {
    return path.isAbsolute(p) ? p : path.resolve(__dirname, p)
}

export function asyncChannel(channel: string, replyChannel, func: (event, uid: string, ...args) => Promise<any>) {
    ipcMain.on(channel, async (event, uid, ...args) => {
        // console.log('=======================================================')
        // console.log('receive', channel, uid, args)
        let resp;
        let error;
        try {
            resp = await func(event, uid, ...args);
        } catch (e) {
            error = e;
        } finally {
            // console.log('response', replyChannel, uid, [resp, error])
            event.sender.send(replyChannel, uid, [resp, error]);
        }
    })
}

async function test() {
    // const ret1 = await files('templates/cafebabe', true)
    // console.log(ret1)
    //
    // const content = await readFile(ret1[0])
    // console.log(content)
    // console.log(await exists('templates/cafebabe'))
    // console.log(await exists('templates/aaaa'))

    const file = 'c:/Users/Misty/Desktop/test/module1/src/main/java/org/misty/test/module1/TTestApplication.java'
    await writeFile(file, 'afdsafsda')
}

// test()
